package com.healthy.util;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import com.healthy.util.PropertiesUtil;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.alipay.config.AlipayConfig;

/**
 * @author ?????
 * @date 2020年6月12日
 * @description <p>支付宝支付工具类</p>
 */
public class AlipayUtil {
	
	/* 支付页面
	 * 
	 * subject 商品名称
	 * body 商品介绍，概览信息
	 * timeout_express 该笔订单允许的最晚付款时间，逾期将关闭交易。取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。 该参数数值不接受小数点， 如 1.5h，可转换为 90m
	 * total_amount 交易额，即收款面额
	 * returnUrlPath 页面跳转同步通知页面路径,Get请求，自定义
	 * notifyUrlPath 自定义异步回调，工程相对路径，如接口名，Post请求，自定义
	 * passback_params 自定义回调参数，如订单号。请求的时候放啥返回就是啥
	 * extend_params 公用扩展参数
	 */
	public String sponserPay(String subject, String body, String total_amount, String timeout_express, String returnUrlPath, String notifyUrlPath, String passback_params, String extend_params) throws IOException{
		JSONObject json = new JSONObject();
		String URL = AlipayConfig.URL;
		String APP_ID  = AlipayConfig.APPID;
		String APP_PRIVATE_KEY = AlipayConfig.RSA_PRIVATE_KEY;
		String FORMAT = AlipayConfig.FORMAT;
		String CHARSET = AlipayConfig.CHARSET;
		String ALIPAY_PUBLIC_KEY = AlipayConfig.ALIPAY_PUBLIC_KEY;
		String SIGN_TYPE = AlipayConfig.SIGNTYPE;
		AlipayClient alipayClient =  new  DefaultAlipayClient(URL,APP_ID,APP_PRIVATE_KEY,FORMAT,CHARSET,ALIPAY_PUBLIC_KEY,SIGN_TYPE);
		AlipayTradePagePayRequest alipayRequest =  new  AlipayTradePagePayRequest(); //创建API对应的request 
		
	    String path=this.getClass().getClassLoader().getResource("default.ini").getPath();
    	File file = new File(path);
    	String serverip = PropertiesUtil.Find("serverip", file);
//    	System.out.println(serverip);  配置文件设置全局网关，根据网关+接口名进行数据回调
    	
    	//在公共参数中设置回跳和通知地址 
		alipayRequest.setReturnUrl( serverip + returnUrlPath );
	    alipayRequest.setNotifyUrl( serverip + notifyUrlPath ); 
	    /*
	     * 往BizContent放订单相关信息，json串
	     * 官方请求参数文档传送门：https://opendocs.alipay.com/apis/api_1/alipay.trade.page.pay
	     */
	    // 交易号，即时间戳
	    json.put("out_trade_no", Dateutil.getTimeStampString());
	    // 销售产品码，商家和支付宝签约的产品码。
	    json.put("product_code", "FAST_INSTANT_TRADE_PAY");
	    // 商品名称
	    json.put("subject", subject);
	    // 产品价格
	    json.put("total_amount", total_amount);
	    // 公用回传参数，如果请求时传递了该参数，则返回给商户时会回传该参数。可拼接扩展参数
	    json.put("passback_params", passback_params+"@#@"+extend_params);
	    // 对一笔交易的具体描述信息
	    json.put("body", body);
	    // 订单有效时间，两分钟
	    json.put("timeout_express", timeout_express);
	    alipayRequest.setBizContent(json.toJSONString()); //填充业务参数 
	    String form= "" ;
	    try  {
	        form = alipayClient.pageExecute(alipayRequest).getBody();  //调用SDK生成表单 
	        return form;
	    }  catch  (AlipayApiException e) {
	        e.printStackTrace();
	    }
		return "";
	}
	
	/**
	 * 验签：支付回调，成功或失败信息
	 * @return
	 * @throws AlipayApiException 
	 * @throws UnsupportedEncodingException 
	 */
	public static Map<String, String> verify(HttpServletRequest request ) throws AlipayApiException, UnsupportedEncodingException{
		// 获取支付宝POST过来反馈信息(官方案例)
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决，这段代码在出现乱码时使用
            // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        // 调用SDK验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);
        if (signVerified) {// 验证成功
            // 交易状态
            String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
            if (trade_status.equals("TRADE_FINISHED")) {
//                System.out.println("交易结束，不可退款");
                return params;
            } else if (trade_status.equals("TRADE_SUCCESS")) {
                return params;
            }
        } else {// 验证失败
        }
		return null;
	}
	
	/**
	 * 退款: refund
	 * 商户订单号和支付宝交易号不能同时为空。 trade_no、  out_trade_no如果同时存在优先取trade_no
	 * @param trade_no 商户订单号，和支付宝交易号二选一
	 * @param out_trade_no 支付宝交易号，和商户订单号二选一
	 * @param refund_amount 退款金额，不能大于订单总金额
	 * @param refund_reason 退款的原因说明
	 * @param out_request_no 标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传。
	 * @throws AlipayApiException 
	 */
	public static void refund(String trade_no, String out_trade_no, String refund_amount, String refund_reason, String out_request_no) throws AlipayApiException{
		
		if(trade_no!=null||out_trade_no!=null){
    		
    		// SDK 公共请求类，包含公共请求参数，以及封装了签名与验签，开发者无需关注签名与验签     
    		AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);

    		AlipayTradeRefundRequest alipay_request = new AlipayTradeRefundRequest();
    		
    		AlipayTradeRefundModel model=new AlipayTradeRefundModel();
    		model.setOutTradeNo(out_trade_no);
    		model.setTradeNo(trade_no);
    		model.setRefundAmount(refund_amount);
    		model.setRefundReason(refund_reason);
    		model.setOutRequestNo(out_request_no);
    		alipay_request.setBizModel(model);
    		
    		AlipayTradeRefundResponse alipay_response =client.execute(alipay_request);
    	    System.out.println(alipay_response.getBody());
    	  }
		
	}
}
